package cn.wolfcode.web.controller;

import cn.wolfcode.domain.Department;
import cn.wolfcode.domain.Employee;
import cn.wolfcode.domain.Role;
import cn.wolfcode.qo.EmployeeQueryObject;
import cn.wolfcode.qo.JsonResult;
import cn.wolfcode.service.IDepartmentService;
import cn.wolfcode.service.IEmployeeService;
import cn.wolfcode.service.IRoleService;
import cn.wolfcode.util.RequiredPermission;
import com.github.pagehelper.PageInfo;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping("/employee")
public class EmployeeController {

    //  获取容器中IEmployeeService的实现类对象，并注入Bean
    @Autowired
    private IEmployeeService employeeService;

    //  获取容器中IDepartmentService的实现类对象，并注入Bean
    @Autowired
    private IDepartmentService departmentService;

    @Autowired
    private IRoleService roleService;

    //  查询方法
    @RequestMapping("/list")
    @RequiredPermission(name = "员工列表", expression = "employee:list")
    public String list(Model model, @ModelAttribute("qo") EmployeeQueryObject qo){
        //  调用Service层的query方法
        PageInfo<Employee> pageInfo = employeeService.query(qo);
        //  将获取到的数据设置到模型中
        model.addAttribute("pageResult", pageInfo);

        //  调用Service层的selectAll方法
        List<Department> departments = departmentService.selectAll();
        //  将获取到的数据设置到模型中
        model.addAttribute("departments",  departments);

        List<Role> roles = roleService.selectAll();
        model.addAttribute("roles", roles);

        //  找视图/WEB-INF/views/employee/list.ftl
        return "employee/list";
    }

    //  删除方法
    @RequestMapping("/delete")
    @RequiredPermission(name = "员工删除", expression = "employee:delete")
    @ResponseBody
    public JsonResult delete(Long id) {
        try {
            //  判断id是否存在
            if (id != null) {
                //  调用Service层的deleteById方法
                employeeService.deleteById(id);
            }
            return new JsonResult(true, "删除成功");
        } catch (Exception ex) {
            ex.printStackTrace();
            return new JsonResult(false, "删除失败");
        }
    }

    //  批量删除方法
    @RequestMapping("/batchDelete")
    @RequiredPermission(name = "批量员工删除", expression = "employee:batchDelete")
    @ResponseBody
    public JsonResult batchDelete(Long[] ids) {
        try {
            //  判断ids不为空且有长度
            if (ids != null && ids.length > 0) {
                //  删除中间表关系
                //  调用Service层的deleteBatchRelation方法
                employeeService.deleteBatchRelation(ids);
                //  删除员工对象
                //  调用Service层的batchDelete方法
                employeeService.batchDelete(ids);
                return new JsonResult(true, "批量删除成功");
            }
            //  若判断失败，则直接抛异常
            throw new RuntimeException("批量删除失败");
        } catch (Exception ex) {
            ex.printStackTrace();
            return new JsonResult(false, ex.getMessage());
        }
    }

    /*
    //  检查用户名方法
    @RequestMapping("/checkName")
    @ResponseBody
    public Map<String, Boolean> checkName(String name) {
        Map<String, Boolean> map = new HashMap<>();
        Employee employee = employeeService.checkName(name);
        map.put("valid", employee == null);
        return map;
    }*/

    @RequestMapping("/checkName")
    @ResponseBody
    public Map<String, Boolean> checkName(String name, Long id) {
        Map<String, Boolean> map = new HashMap<>();
        if (id != null) {
            Employee employee = employeeService.selectById(id);
            if (employee.getName().equals(name) && employee.getId().equals(id)) {
                map.put("valid", true);
            } else if (!employee.getName().equals(name)){
                map.put("valid", true);
            } else {
                map.put("valid", false);
            }
        } else {
            Employee employee = employeeService.checkName(name);
            map.put("valid", employee == null);
        }
        return map;
    }

    //  去新增或修改页面方法
    @RequestMapping("/input")
    @RequiredPermission(name = "员工编辑", expression = "employee:input")
    public String input(Long id, Model model){
        //  调用Service层的selectAll方法
        List<Department> departments = departmentService.selectAll();
        //  将获取到的数据设置到模型中
        model.addAttribute("departments",  departments);

        List<Role> roles = roleService.selectAll();
        model.addAttribute("roles", roles);


        //  判断id是否存在
        if (id != null) {
            //  调用Service层的selectById方法
            Employee employee = employeeService.selectById(id);
            //  将获取到的数据设置到模型中
            model.addAttribute("employee", employee);
        }
        //  找视图/WEB-INF/views/employee/input.ftl
        return "employee/input";
    }

    //  新增或修改页面方法
    @RequestMapping("/saveOrUpdate")
    @RequiredPermission(name = "员工保存或更新", expression = "employee:saveOrUpdate")
    @ResponseBody
    public JsonResult saveOrUpdate(Employee employee, Long[] ids) {
        try {
            //  判断id是否存在
            if (employee.getId() != null) {
                //  若存在，调用Service层的updateById方法
                employeeService.updateById(employee, ids);
            } else {
                //  若不存在，调用Service层的insert方法
                employeeService.insert(employee, ids);
            }
            return new JsonResult(true, "操作成功");
        } catch (Exception e) {
            e.printStackTrace();
            return new JsonResult(false, "操作成功");
        }
    }


    @RequestMapping("/updatePwdList")
    public String updatePwdList(){
        //  跳转修改密码页面
        return "/employee/updatePwd";
    }

    @RequestMapping("/updatePwd")
    @ResponseBody
    public JsonResult updatePwd(String oldPassword, String newPassword){
        try {
            //  获取主体对象
            Subject subject = SecurityUtils.getSubject();
            //  强转为员工对象
            Employee employee = (Employee) subject.getPrincipal();

            //  设置密码加密
            Md5Hash md5HashOld = new Md5Hash(oldPassword, employee.getName(), 1);
            Md5Hash md5HashNew = new Md5Hash(newPassword, employee.getName(), 1);

            //  判断当前登录用户的密码与前台发送的请求中的密码是否一致
            if (employee.getPassword().equals(md5HashOld.toString())) {
                //  若相同，则执行修改密码的方法
                employeeService.setNewPassword(employee.getId(), md5HashNew.toString());
                return new JsonResult(true, "修改成功");
            }
            //  若判断不一致，直接抛出异常
            throw new RuntimeException("原密码错误");
        } catch (Exception ex) {
            ex.printStackTrace();
            //  返回捕获异常的信息
            return new JsonResult(false, ex.getMessage());
        }
    }

    @RequiredPermission(name = "员工重置密码页面", expression = "employee:resetPwdList")
    @RequestMapping("/resetPwdList")
    public String resetPwdList(Model model, Long id){
        //  根据id查询员工对象
        Employee employee = employeeService.selectById(id);
        //  将员工的名字和id存入模型中
        model.addAttribute("employeeName", employee.getName());
        model.addAttribute("employeeId", employee.getId());
        //  跳转页面
        return "/employee/resetPwd";
    }

    @RequiredPermission(name = "员工重置密码", expression = "employee:resetPwd")
    @RequestMapping("/resetPwd")
    @ResponseBody
    public JsonResult resetPwd(Long id, String newPassword){
        try {
            //  根据id查询员工对象
            Employee employee = employeeService.selectById(id);
            //  若该员工对象存在
            if (employee != null) {
                //  设置密码加密
                Md5Hash md5HashNew = new Md5Hash(newPassword, employee.getName(), 1);
                //  若存在，则执行修改密码的方法
                employeeService.setNewPassword(employee.getId(), md5HashNew.toString());
                return new JsonResult(true, "修改成功");
            }
            //  若不存在，直接抛出异常
            throw new RuntimeException("修改失败");
        } catch (Exception ex) {
            ex.printStackTrace();
            //  返回捕获异常的信息
            return new JsonResult(false, ex.getMessage());
        }
    }

    //  导出
    @RequestMapping("/exportXls")
    public void exportXls(HttpServletResponse response) throws IOException {
        //  文件下载的响应头（让浏览器访问资源的的时候以下载的方式打开）
        response.setHeader("Content-Disposition","attachment;filename=employee.xls");

        //  调用方法
        Workbook workbook = employeeService.exportXls();

        //  将数据写出去
        workbook.write(response.getOutputStream());
    }

    //  导入
    @RequestMapping("/importXls")
    @ResponseBody
    public JsonResult importXls(MultipartFile file) throws IOException {

        //  将提交过来的表单以流的形式设置到文件中去
        Workbook workbook = new HSSFWorkbook(file.getInputStream());

        //  调用方法
        employeeService.importXls(workbook);

        //  返回json
        return new JsonResult(true, "操作成功");
    }

    //  禁用
    @RequestMapping("/forbidden")
    @ResponseBody
    public JsonResult forbidden(Long fid, boolean fstatus){
        employeeService.updateByStatus(fid, fstatus);
        return new JsonResult(true, "操作成功");
    }

    //  恢复
    @RequestMapping("/recover")
    @ResponseBody
    public JsonResult recover(Long rid, boolean rstatus){
        employeeService.updateByStatus(rid, rstatus);
        return new JsonResult(true, "操作成功");
    }
}
